#include "SSL_Thread_Init.h"


void SSL_thread_setup(void) {
  int i;
  
  lock_cs=(pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
  lock_count=(long *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
  for (i=0; i<CRYPTO_num_locks(); i++) {
    lock_count[i]=0;
    pthread_mutex_init(&(lock_cs[i]),NULL);
  }

  CRYPTO_set_id_callback((unsigned long (*)())SSL_pthreads_thread_id);
  CRYPTO_set_locking_callback((void (*)())SSL_pthreads_locking_callback);
}

void SSL_thread_cleanup(void) {
  int i;
  CRYPTO_set_id_callback(NULL);
  CRYPTO_set_locking_callback(NULL);
  fprintf(stderr,"cleanup\n");
  for (i=0; i<CRYPTO_num_locks(); i++) {
    pthread_mutex_destroy(&(lock_cs[i]));
    fprintf(stderr,"%8ld:%s\n",lock_count[i], CRYPTO_get_lock_name(i));
  }
  OPENSSL_free(lock_cs);
  OPENSSL_free(lock_count);
  fprintf(stderr,"done cleanup\n");
}

void SSL_pthreads_locking_callback(int mode, int type, char *file, int line) {
#ifdef undef
  fprintf(stderr,"thread=%4d mode=%s lock=%s %s:%d\n",
          CRYPTO_thread_id(),
          (mode&CRYPTO_LOCK)?"l":"u",
          (type&CRYPTO_READ)?"r":"w",file,line);
#endif

/*
        if (CRYPTO_LOCK_SSL_CERT == type)
                fprintf(stderr,"(t,m,f,l) %ld %d %s %d\n",
                CRYPTO_thread_id(),
                mode,file,line);
*/
  if (mode & CRYPTO_LOCK) {
    pthread_mutex_lock(&(lock_cs[type]));
    lock_count[type]++;
  } else {
    pthread_mutex_unlock(&(lock_cs[type]));
  }
}

unsigned long SSL_pthreads_thread_id(void) {
  return ((unsigned long)pthread_self());
}
